home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / comm2 / xbtx.lha / Source / IORawSerial.cpp < prev    next >
C/C++ Source or Header  |  1995-12-03  |  8KB  |  401 lines

  1. /*
  2. **    $Id: IORawSerial.cpp 1.5 1995/12/03 12:16:23 olsen Exp olsen $
  3. **
  4. **    :ts=4
  5. */
  6.  
  7. /*
  8.  * Copyright © 1995 by Olaf Barthel, All Rights Reserved
  9.  *
  10.  * Redistribution and use in source and binary forms, with or without
  11.  * modification, are permitted provided that the following conditions
  12.  * are met:
  13.  * 1. Redistributions of source code must retain the above copyright
  14.  *    notice, this list of conditions and the following disclaimer.
  15.  * 2. Redistributions in binary form must reproduce the above copyright
  16.  *    notice, this list of conditions and the following disclaimer in the
  17.  *    documentation and/or other materials provided with the distribution.
  18.  *
  19.  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
  20.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
  22.  * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  24.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  25.  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  26.  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  27.  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  28.  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29.  *
  30.  * This software has not been validated by the ``Bundesamt fuer Zulassungen in
  31.  * der Telekommunikation'' of the ``Deutsche Bundepost Telekom'' and thus
  32.  * must not be used for accessing the BTX-Network of the Telekom in Germany.
  33.  *
  34.  * Diese Software hat keine Zulassung durch das Bundesamt fuer Zulassungen in
  35.  * der Telekommunikation der Deutschen Bundespost Telekom und darf daher nicht
  36.  * am Netz der Deutschen Bundespost Telekom in Deutschland betrieben werden.
  37.  */
  38.  
  39. /****************************************************************************/
  40.  
  41. #include <exec/memory.h>
  42. #include <exec/errors.h>
  43.  
  44. #include <devices/serial.h>
  45. #include <devices/timer.h>
  46.  
  47. #include <hardware/cia.h>
  48.  
  49. #include <clib/exec_protos.h>
  50.  
  51. #ifdef __SASC
  52. #include <pragmas/exec_pragmas.h>
  53.  
  54. extern struct ExecBase *SysBase;
  55. #endif    // _SASC
  56.  
  57. #include <string.h>
  58. #include <stdio.h>
  59.  
  60. /****************************************************************************/
  61.  
  62. #ifndef _IORAWSERIAL_HPP
  63. #include "IORawSerial.hpp"
  64. #endif
  65.  
  66. /****************************************************************************/
  67.  
  68. VOID IORawSerial::StopRead(VOID)
  69. {
  70.     if(Valid && Reading)
  71.     {
  72.         if(!CheckIO((struct IORequest *)ReadRequest))
  73.             AbortIO((struct IORequest *)ReadRequest);
  74.  
  75.         WaitIO((struct IORequest *)ReadRequest);
  76.  
  77.         Reading = FALSE;
  78.     }
  79.  
  80.     SetSignal(0,ReadMask);
  81. }
  82.  
  83. VOID IORawSerial::StartRead(VOID)
  84. {
  85.     if(Valid)
  86.     {
  87.         StopRead();
  88.  
  89.         ReadRequest->IOSer.io_Command    = CMD_READ;
  90.         ReadRequest->IOSer.io_Data        = &SingleChar;
  91.         ReadRequest->IOSer.io_Length    = 1;
  92.  
  93.         SendIO((struct IORequest *)ReadRequest);
  94.  
  95.         Reading = TRUE;
  96.     }
  97. }
  98.  
  99. BYTE IORawSerial::WaitRead(VOID)
  100. {
  101.     BYTE Error;
  102.  
  103.     if(Valid)
  104.     {
  105.         if(Reading)
  106.         {
  107.             Error = WaitIO((struct IORequest *)ReadRequest);
  108.  
  109.             Reading = FALSE;
  110.         }
  111.         else
  112.             Error = 0;
  113.     }
  114.     else
  115.         Error = IOERR_OPENFAIL;
  116.  
  117.     return(Error);
  118. }
  119.  
  120. VOID IORawSerial::Close(VOID)
  121. {
  122.     if(Valid)
  123.     {
  124.         StopRead();
  125.         StopTime();
  126.  
  127.         CloseDevice((struct IORequest *)TimeRequest);
  128.  
  129.         DeleteIORequest((struct IORequest *)TimeRequest);
  130.  
  131.         DeleteMsgPort(TimePort);
  132.  
  133.         CloseDevice((struct IORequest *)ReadRequest);
  134.  
  135.         DeleteIORequest((struct IORequest *)ReadRequest);
  136.  
  137.         FreeVec(WriteRequest);
  138.  
  139.         DeleteMsgPort(WritePort);
  140.  
  141.         DeleteMsgPort(ReadPort);
  142.  
  143.         Valid = FALSE;
  144.     }
  145. }
  146.  
  147. LONG IORawSerial::Open(CONST STRPTR Channel,ULONG Unit,ULONG Baud,BOOL RTS_CTS)
  148. {
  149.     if(ReadPort = CreateMsgPort())
  150.     {
  151.         ReadMask = 1UL << ReadPort->mp_SigBit;
  152.  
  153.         if(WritePort = CreateMsgPort())
  154.         {
  155.             if(ReadRequest = (struct IOExtSer *)CreateIORequest(ReadPort,sizeof(struct IOExtSer)))
  156.             {
  157.                 if(WriteRequest = (struct IOExtSer *)AllocVec(sizeof(struct IOExtSer),MEMF_ANY | MEMF_PUBLIC))
  158.                 {
  159.                     if(!OpenDevice((UBYTE *)Channel,Unit,(struct IORequest *)ReadRequest,NULL))
  160.                     {
  161.                         ReadRequest->IOSer.io_Command    = SDCMD_SETPARAMS;
  162.                         ReadRequest->io_ExtFlags        = 0;
  163.                         ReadRequest->io_ReadLen            = 8;
  164.                         ReadRequest->io_WriteLen        = 8;
  165.                         ReadRequest->io_StopBits        = 1;
  166.  
  167.                         if(Baud)
  168.                             ReadRequest->io_Baud = Baud;
  169.  
  170.                         ReadRequest->io_SerFlags = (UBYTE)((ReadRequest->io_SerFlags & SERF_7WIRE) | SERF_XDISABLED);
  171.  
  172.                         if(RTS_CTS >= FALSE)
  173.                         {
  174.                             if(RTS_CTS)
  175.                                 ReadRequest->io_SerFlags |=  SERF_7WIRE;
  176.                             else
  177.                                 ReadRequest->io_SerFlags &= ~SERF_7WIRE;
  178.                         }
  179.  
  180.                         if(!DoIO((struct IORequest *)ReadRequest))
  181.                         {
  182.                             CopyMem(ReadRequest,WriteRequest,sizeof(struct IOExtSer));
  183.  
  184.                             WriteRequest->IOSer.io_Message.mn_ReplyPort = WritePort;
  185.  
  186.                             if(TimePort = CreateMsgPort())
  187.                             {
  188.                                 TimeMask = 1UL << TimePort->mp_SigBit;
  189.  
  190.                                 if(TimeRequest = (struct timerequest *)CreateIORequest(TimePort,sizeof(struct timerequest)))
  191.                                 {
  192.                                     if(!OpenDevice((UBYTE *)TIMERNAME,UNIT_VBLANK,(struct IORequest *)TimeRequest,NULL))
  193.                                     {
  194.                                         Valid = TRUE;
  195.  
  196.                                         StartRead();
  197.  
  198.                                         return(0);
  199.                                     }
  200.  
  201.                                     DeleteIORequest((struct IORequest *)TimeRequest);
  202.                                     TimeRequest = NULL;
  203.                                 }
  204.  
  205.                                 DeleteMsgPort(TimePort);
  206.                                 TimePort = NULL;
  207.                             }
  208.                         }
  209.  
  210.                         CloseDevice((struct IORequest *)ReadRequest);
  211.                     }
  212.  
  213.                     FreeVec(WriteRequest);
  214.                     WriteRequest = NULL;
  215.                 }
  216.  
  217.                 DeleteIORequest((struct IORequest *)ReadRequest);
  218.                 ReadRequest = NULL;
  219.             }
  220.  
  221.             DeleteMsgPort(WritePort);
  222.             WritePort = NULL;
  223.         }
  224.  
  225.         DeleteMsgPort(ReadPort);
  226.         ReadPort = NULL;
  227.     }
  228.  
  229.     return(-1);
  230. }
  231.  
  232. LONG IORawSerial::GetChar(LONG Timeout)
  233. {
  234.     LONG Result;
  235.  
  236.     if(Valid)
  237.     {
  238.         if(Reading)
  239.         {
  240.             if(CheckIO((struct IORequest *)ReadRequest))
  241.             {
  242.                 if(WaitRead())
  243.                     Result = CHANNELERR_Nothing;
  244.                 else
  245.                     Result = (LONG)SingleChar;
  246.  
  247.                 StartRead();
  248.             }
  249.             else
  250.             {
  251.                 if(Timeout)
  252.                 {
  253.                     ULONG Signals;
  254.  
  255.                     StartTime(Timeout);
  256.  
  257.                     for(;;)
  258.                     {
  259.                         Signals = Wait(ReadMask | TimeMask);
  260.  
  261.                         if(Signals & ReadMask)
  262.                         {
  263.                             if(WaitRead())
  264.                                 Result = CHANNELERR_Nothing;
  265.                             else
  266.                                 Result = (LONG)SingleChar;
  267.  
  268.                             StopTime();
  269.  
  270.                             StartRead();
  271.  
  272.                             break;
  273.                         }
  274.  
  275.                         if(Signals & TimeMask)
  276.                         {
  277.                             WaitTime();
  278.  
  279.                             Result = CHANNELERR_Timeout;
  280.  
  281.                             break;
  282.                         }
  283.                     }
  284.                 }
  285.                 else
  286.                     Result = CHANNELERR_Nothing;
  287.             }
  288.         }
  289.         else
  290.             Result = CHANNELERR_Nothing;
  291.     }
  292.     else
  293.         Result = CHANNELERR_EOF;
  294.  
  295.     return(Result);
  296. }
  297.  
  298. VOID IORawSerial::PutString(CONST STRPTR String,LONG Len)
  299. {
  300.     if(Valid)
  301.     {
  302.         if(Len < 0)
  303.             Len = strlen(String);
  304.  
  305.         WriteRequest->IOSer.io_Command    = CMD_WRITE;
  306.         WriteRequest->IOSer.io_Data     = (APTR)String;
  307.         WriteRequest->IOSer.io_Length    = Len;
  308.  
  309.         DoIO((struct IORequest *)WriteRequest);
  310.     }
  311. }
  312.  
  313. LONG IORawSerial::Waiting(VOID)
  314. {
  315.     if(Valid)
  316.     {
  317.         if(Reading)
  318.         {
  319.             if(CheckIO((struct IORequest *)ReadRequest))
  320.                 return(1);
  321.         }
  322.  
  323.         WriteRequest->IOSer.io_Command = SDCMD_QUERY;
  324.  
  325.         DoIO((struct IORequest *)WriteRequest);
  326.  
  327.         return((LONG)WriteRequest->IOSer.io_Actual);
  328.     }
  329.     else
  330.         return(0);
  331. }
  332.  
  333. ULONG IORawSerial::WaitMask(VOID)
  334. {
  335.     return(ReadMask);
  336. }
  337.  
  338. IORawSerial::IORawSerial()
  339. {
  340.     Reading    = FALSE;
  341.     Ticking    = FALSE;
  342.     Valid    = FALSE;
  343. }
  344.  
  345. IORawSerial::~IORawSerial()
  346. {
  347.     Close();
  348. }
  349.  
  350. VOID IORawSerial::StartTime(ULONG Seconds,ULONG Micros)
  351. {
  352.     StopTime();
  353.  
  354.     TimeRequest->tr_node.io_Command = TR_ADDREQUEST;
  355.     TimeRequest->tr_time.tv_secs    = Seconds;
  356.     TimeRequest->tr_time.tv_micro    = Micros;
  357.  
  358.     SendIO((struct IORequest *)TimeRequest);
  359.  
  360.     Ticking = TRUE;
  361. }
  362.  
  363. VOID IORawSerial::StopTime(VOID)
  364. {
  365.     if(Ticking)
  366.     {
  367.         if(!CheckIO((struct IORequest *)TimeRequest))
  368.             AbortIO((struct IORequest *)TimeRequest);
  369.  
  370.         WaitTime();
  371.     }
  372.  
  373.     SetSignal(0,TimeMask);
  374. }
  375.  
  376. VOID IORawSerial::WaitTime(VOID)
  377. {
  378.     if(Ticking)
  379.     {
  380.         WaitIO((struct IORequest *)TimeRequest);
  381.  
  382.         Ticking = FALSE;
  383.     }
  384. }
  385.  
  386. VOID IORawSerial::Flush(VOID)
  387. {
  388.     if(Valid)
  389.     {
  390.         BOOL IsReading = Reading;
  391.  
  392.         StopRead();
  393.  
  394.         WriteRequest->IOSer.io_Command = CMD_CLEAR;
  395.         DoIO((struct IORequest *)WriteRequest);
  396.  
  397.         if(IsReading)
  398.             StartRead();
  399.     }
  400. }
  401.